﻿using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using IEx.Common;
using IEx.Model.Partials;
using IEx.Utilities;

namespace IEx.ParserBuilder.Tamtay
{
    public class TamtayParser : IHtmlParser
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="html"></param>
        /// <param name="attachResultItem"></param>
        /// <param name="attachNewItemSource"></param>
        public void Parse(SourceItem item, string html, Action<Model.Partials.Announcement> attachResultItem, Action<SourceItem> attachNewItemSource)
        {
            try
            {
                string containerId = "id=\"container\"";
                string pageNavId = "id=\"page-nav\"";
                string remainHtml = Utility.GetHtmlBody(html, containerId, pageNavId);
                List<Announcement> detectedAnnouncements = new List<Announcement>();
                Uri newUri = Utility.CreateNewUriForNextPage(item.Url);

                if (!string.IsNullOrEmpty(remainHtml))
                {
                    Regex regImages = new Regex("class=\"item\">.*?\\s</ul>");
                    MatchCollection mImages = regImages.Matches(remainHtml);

                    for (int i = 0; i < mImages.Count; i++)
                    {
                        string albumUrl = string.Empty;
                        string user = string.Empty;
                        string dateTime = string.Empty;
                        string title = string.Empty;
                        string linkImgThumb = string.Empty;
                        DateTime postDate = DateTime.Now;

                        string imgBlockContent = mImages[i].Value.Trim();

                        Regex regImg = new Regex("<div class=\"img\">.*?</div>");
                        Match mImg = regImg.Match(imgBlockContent);
                        if (mImg.Success)
                        {
                            string imgHtml = mImg.Value.Trim();
                            albumUrl = new Uri(newUri, RegexUtility.ExtractHyperlink(imgHtml)).ToString();
                            linkImgThumb = RegexUtility.ExtractSrcFromImgTag(imgHtml);
                        }

                        Regex regTitle = new Regex("<h3 style=\".*?\">.*?</h3>");
                        Match mTitle = regTitle.Match(imgBlockContent);
                        if (mTitle.Success)
                        {
                            string titleHtml = mTitle.Value.Trim();
                            title = RegexUtility.ExtractTextFromHtmlTag(titleHtml);
                        }

                        Regex regUser = new Regex("<div class=\"userUploaded\">.*?</div>");
                        Match mUser = regUser.Match(imgBlockContent);
                        if (mUser.Success)
                        {
                            string userHtml = mUser.Value.Trim();
                            user = RegexUtility.ExtractTextFromHtmlTag(userHtml);
                        }

                        Regex regDateTime = new Regex("<div class=\"dateUploadedAlbum\">.*?</div>");
                        Match mDateTime = regDateTime.Match(imgBlockContent);
                        if (mDateTime.Success)
                        {
                            string dateTimeHtml = mDateTime.Value.Trim();
                            dateTime = RegexUtility.ExtractTextFromHtmlTag(dateTimeHtml);
                            if (!string.IsNullOrEmpty(dateTime))
                            {
                                postDate = Utility.ConvertToDateTimeObject(dateTime, item.DateTimeFormat);
                            }
                        }
                        List<Photo> album =new List<Photo>();
                        if (!string.IsNullOrEmpty(albumUrl))
                        {
                            //Extract album
                             album = ExtractAlbumInfo(albumUrl, item);
                        }

                        if (!string.IsNullOrEmpty(linkImgThumb) && !string.IsNullOrEmpty(title))
                        {
                            Announcement ann = new Announcement();
                            ann.Link = linkImgThumb;
                            ann.InsertedDate = DateTime.Now;
                            ann.LangId = item.LangId;
                            ann.SourceCode = item.SourceCode;
                            ann.SourceId = item.SourceId;
                            ann.DateTime = postDate;
                            ann.DateNumberic = long.Parse(
                                            postDate.ToString("yyyyMMddHHmmss"));
                            ann.Title = title;
                            ann.SocialNetwork.Photos = album;
                            ann.Message = string.Empty;
                            detectedAnnouncements.Add(ann);
                        }
                    }
                }
                // insert into download queue when no error in parsing
                foreach (Announcement ann in detectedAnnouncements)
                {
                    attachResultItem(ann);
                }
            }
            catch (Exception ex)
            {
                // if has an error, save fail request to next time scanning
                if (item.FailId == 0)
                {
                    item.FailId = DateTime.Now.Ticks;
                    Utility.SaveFailRequests(item);
                }

                // then write log
                string message = string.Format(@"
            Company code:   {0}
            HTML Parsing:   Fail
            Request URL:    {1}
            Search key:     {2}", item.SourceCode, item.Url, item.SearchCode);
                Logger.WriteError(message, ex);
            }
        }

        #region Extract image file from Tamtay.vn

        /// <summary>
        /// 
        /// </summary>
        /// <param name="albumUrl"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        private static List<Photo> ExtractAlbumInfo(string albumUrl, SourceItem item)
        {
            Logger.Debug("***SCANNING ALBUM URL: " + albumUrl);
            HttpStatusCode status = HttpStatusCode.Accepted;
            string html = Utility.LoadHtml(albumUrl, ref status);

            try
            {
                if (!string.IsNullOrEmpty(html))
                {
                    string containerLeftId = "id=\"containerLeft\"";
                    string containerRight = "id=\"album_related\"";
                    string remainHtml = Utility.GetHtmlBody(html, containerLeftId, containerRight);
                    string attachmentLinks = string.Empty;
                    string fileExtentions = string.Empty;
                    List<Photo> album = new List<Photo>();
                    if (!string.IsNullOrEmpty(remainHtml))
                    {
                        Regex regImgs = new Regex("<p class=\"t_center\">.*?</p>");
                        MatchCollection mImgs = regImgs.Matches(remainHtml);
                        for (int i = 0; i < mImgs.Count; i++)
                        {
                            string bockImage = mImgs[i].Value.Trim();
                            Photo photo = new Photo();
                            string link = RegexUtility.ExtractSrcFromImgTag(bockImage);
                            attachmentLinks = link;
                            fileExtentions = Utility.GetFileExtention(link);
                            if (!string.IsNullOrEmpty(attachmentLinks) && !string.IsNullOrEmpty(fileExtentions))
                            {
                                photo.AttachmentLinks = attachmentLinks;
                                photo.ImageExtention = fileExtentions;
                                album.Add(photo);
                            }
                        }
                        return album;
                    }
                }
                return new List<Photo>();
            }
            catch (Exception ex)
            {
                // if has an error, save fail request to next time scanning
                if (item.FailId == 0)
                {
                    item.FailId = DateTime.Now.Ticks;
                    Utility.SaveFailRequests(item);
                }
                // then write log
                string message = string.Format(@"
            Extract Album details
            Source code:   {0}
            HTML Parsing:   Fail
            Request URL:    {1}", item.SourceCode, albumUrl);
                Logger.WriteError(message, ex);
                return null;
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private static ImageFormat GetImageFormat(string fileName)
        {
            string extension = Path.GetExtension(fileName);
            if (string.IsNullOrEmpty(extension))
                throw new ArgumentException(
                    string.Format("Unable to determine file extension for fileName: {0}", fileName));

            switch (extension.ToLower())
            {
                case @".bmp":
                    return ImageFormat.Bmp;

                case @".gif":
                    return ImageFormat.Gif;

                case @".ico":
                    return ImageFormat.Icon;

                case @".jpg":
                case @".jpeg":
                    return ImageFormat.Jpeg;

                case @".png":
                    return ImageFormat.Png;

                case @".tif":
                case @".tiff":
                    return ImageFormat.Tiff;

                case @".wmf":
                    return ImageFormat.Wmf;

                default:
                    throw new NotImplementedException();
            }
        }

        #endregion
    }
}
